package dialect

import (
	errors2 "server/framework/orm/errors"
	"server/framework/orm/predicate"
	"server/framework/orm/session/model"
	"strings"
)

type MysqlDialect struct {
	builder strings.Builder
	args    []interface{}
}

func (s *MysqlDialect) Quote() string {
	return "`"
}

func (s *MysqlDialect) BuildUpdate(updater *Updater, model *model.Model) (*UpdateStat, error) {

	s.builder.WriteString(" on duplicate key update ")
	for i, assignment := range updater.Assignments {
		switch assign := assignment.(type) {
		case predicate.Column:
			col, ok := model.ColToFieldMap[assign.ColumnName]
			if !ok {
				return nil, errors2.ErrNotFoundColumn(assign.ColumnName)
			}
			s.builder.WriteString(col.FieldName)
			s.builder.WriteString("=values(" + col.FieldName + ")")
		case predicate.Assignment:
			col, ok := model.ColToFieldMap[assign.Column.ColumnName]
			if !ok {
				return nil, errors2.ErrNotFoundColumn(assign.Column.ColumnName)
			}
			s.builder.WriteString(col.FieldName)
			s.builder.WriteString("=?")
			s.args = append(s.args, assign.Val)
		default:
			return nil, errors2.ErrUnknownAssignable(assignment)
		}

		if i < len(updater.Assignments)-1 {
			s.builder.WriteString(",")
		}
	}
	defer func() {
		s.args = make([]interface{}, 0)
		s.builder.Reset()
	}()
	return &UpdateStat{
		SQL:  s.builder.String(),
		Args: s.args,
	}, nil
}

func NewMysqlDialect() *MysqlDialect {
	return &MysqlDialect{}
}

var _ Dialect = &MysqlDialect{}
